package com.zhuss.product.site;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

import org.gavaghan.geodesy.Ellipsoid;
import org.gavaghan.geodesy.GlobalCoordinates;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.zhuss.bean.bo.product.site.AllSiteBo;
import com.zhuss.bean.bo.product.site.ContainSiteBo;
import com.zhuss.bean.bo.product.site.DetailSiteBo;
import com.zhuss.bean.bo.product.site.SearchSiteBo;
import com.zhuss.bean.unit.core.site.SiteBean;
import com.zhuss.bean.vo.product.site.ListSiteVo;
import com.zhuss.common.ReadService;
import com.zhuss.common.SelectVo;
import com.zhuss.core.processor.cache.ConfigCache;
import com.zhuss.enums.IsEnum;
import com.zhuss.exception.DzcxException;
import com.zhuss.product.processor.SiteRead;
import com.zhuss.product.processor.cache.SiteCache;
import com.zhuss.util.DistanceUtil;
import com.zhuss.util.SiteRange;

/**
 * @description: 站点查询Service
 * @author: zhushanshuo
 * @create: Wed Dec 30 08:43:41 CST 2020
 **/
@Component("siteReadService")
public class SiteReadService implements ReadService<Object, Object> {

	@Autowired
	@Qualifier("siteRead")
	private SiteRead siteRead;

	@Autowired
	@Qualifier("siteCache")
	private SiteCache siteCache;

	@Autowired
    private ConfigCache configCache;
	
	/**
	 * 详情
	 */
	@Override
	public Object detail(Object param) throws DzcxException {
		DetailSiteBo bo = (DetailSiteBo) param;
		Long siteId = bo.getSiteId();
		Object vo = siteRead.detail(siteId);
		return vo;
	}

	/**
	 * 列表
	 */
	@Override
	public Object list(Object param) {
		SearchSiteBo bo = (SearchSiteBo) param;
		Object result = siteRead.list(bo);
		return result;
	}


	public List<ListSiteVo> allSite(AllSiteBo bo) throws DzcxException {
		return siteRead.allSite(bo);
	}

	private List<SiteBean> allSite(Integer isAll) throws DzcxException {
		List<SiteBean> all = siteCache.getList(IsEnum.是.key());
		List<SiteBean> noActive = new ArrayList<SiteBean>(all);
		List<SiteBean> hasLine = siteCache.getList(IsEnum.否.key());
		noActive.removeAll(hasLine);
		if (IsEnum.否.sameKey(isAll)) {
			all.stream().filter(item -> noActive.contains(item)).forEach(item -> {
				item.setActive(IsEnum.否.key());
			});
		}
		return all;
	}

	public Object containSite(ContainSiteBo param) throws DzcxException {
		Double km = param.getKm();
		if (km == null || km > 5d || km < 0.2) {
			km = null;
		}
		List<SelectVo> latKmList = configCache.getLatList();
		List<SelectVo> lngKmList = configCache.getLngList();
		final String orignLat = SiteRange.roundLat(param.getLat());
		final String orignLng = SiteRange.roundLng(param.getLng());
		List<Double> latList = SiteRange.rangeLat(km == null ? Double.valueOf(latKmList.get(0).getName()) : km, Double.valueOf(orignLat));
		List<Double> lngList = SiteRange.rangeLng(km == null ? Double.valueOf(lngKmList.get(0).getName()) : km, Double.valueOf(orignLng));
		List<SiteBean> siteList = allSite(param.getIsAll()).stream().filter(item -> Double.valueOf(item.getLat()) >= latList.get(0) && Double.valueOf(item.getLat()) <= latList.get(1) && Double.valueOf(item.getLng()) >= lngList.get(0) && Double.valueOf(item.getLng()) <= lngList.get(1)).collect(Collectors.toList());
		final Double lat = Double.valueOf(orignLat);
		final Double lng = Double.valueOf(orignLng);
		GlobalCoordinates orign = new GlobalCoordinates(lat, lng);

		Collections.sort(siteList, new Comparator<SiteBean>() {

			@Override
			public int compare(SiteBean o1, SiteBean o2) {
		        GlobalCoordinates o1nate = new GlobalCoordinates(Double.valueOf(o1.getLat()), Double.valueOf(o1.getLng()));
		        GlobalCoordinates o2nate = new GlobalCoordinates(Double.valueOf(o2.getLat()), Double.valueOf(o2.getLng()));
		        Double distance1 = DistanceUtil.getDistanceMeter(orign, o1nate, Ellipsoid.Sphere);
		        Double distance2 = DistanceUtil.getDistanceMeter(orign, o2nate, Ellipsoid.Sphere);
				return (int) (distance1.doubleValue() - distance2);
			}
		});

		return siteList;
	}

}

